home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
ctags.lha
/
ctags-3.0.3
/
parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-17
|
59KB
|
2,165 lines
/*****************************************************************************
* $Id: parse.c,v 7.4 1998/12/20 05:57:12 darren Exp $
*
* Copyright (c) 1996-1998, Darren Hiebert
*
* This source code is released for free distribution under the terms of the
* GNU General Public License.
*
* This module contains functions for parsing and scanning of a source file.
*****************************************************************************/
/*============================================================================
= Include files
============================================================================*/
#include "general.h"
#include <string.h>
#include <setjmp.h>
#include "ctags.h"
#include "debug.h"
#include "entry.h"
#include "get.h"
#include "keyword.h"
#include "main.h"
#include "options.h"
#include "parse.h"
#include "read.h"
/*============================================================================
= Macros
============================================================================*/
#define MaxFields 2
#define stringValue(a) #a
#define activeToken(st) ((st)->token[(int)(st)->tokenIndex])
#define parentDecl(st) ((st)->parent == NULL ? \
DECL_NONE : (st)->parent->declaration)
#define isType(token,t) (boolean)((token)->type == (t))
#define isMember(st) (boolean)((st)->member.isMember)
#define insideEnumBody(st) (boolean)((st)->parent == NULL ? FALSE : \
((st)->parent->declaration == DECL_ENUM))
#define isExternCDecl(st,c) (boolean)((c) == STRING_SYMBOL && \
!(st)->haveQualifyingName && (st)->scope == SCOPE_EXTERN)
#define isOneOf(c,s) (boolean)(strchr((s), (c)) != NULL)
/*============================================================================
= Data declarations
============================================================================*/
enum { NumTokens = 3 };
typedef enum eException {
ExceptionNone, ExceptionEOF, ExceptionFormattingError,
ExceptionBraceFormattingError
} exception_t;
/* Used to specify type of keyword.
*/
typedef enum eKeywordId {
KEYWORD_NONE,
KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,
KEYWORD_BOOLEAN, KEYWORD_BYTE,
KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST,
KEYWORD_DOUBLE,
KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN, KEYWORD_EXTENDS,
KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FRIEND,
KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT,
KEYWORD_INTERFACE,
KEYWORD_LONG,
KEYWORD_MUTABLE,
KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NATIVE,
KEYWORD_OPERATOR, KEYWORD_OVERLOAD,
KEYWORD_PACKAGE, KEYWORD_PRIVATE, KEYWORD_PROTECTED, KEYWORD_PUBLIC,
KEYWORD_REGISTER,
KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRUCT,
KEYWORD_SYNCHRONIZED,
KEYWORD_TEMPLATE, KEYWORD_THROW, KEYWORD_THROWS, KEYWORD_TRANSIENT,
KEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME,
KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USING,
KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,
KEYWORD_WCHAR_T
} keywordId;
/* Used to determine whether keyword is valid for the current language and
* what its ID is.
*/
typedef struct sKeywordDesc {
const char *name;
keywordId id;
short isValid[LANG_COUNT]; /* indicates languages for which kw is valid */
} keywordDesc;
/* Used for reporting the type of object parsed by nextToken().
*/
typedef enum eTokenType {
TOK_NONE, /* none */
TOK_ARGS, /* a parenthetical pair and its contents */
TOK_BRACE_CLOSE,
TOK_BRACE_OPEN,
TOK_COMMA, /* the comma character */
TOK_KEYWORD,
TOK_NAME, /* an unknown name */
TOK_PACKAGE, /* a Java package name */
TOK_PAREN_NAME, /* a single name in parentheses */
TOK_SEMICOLON, /* the semicolon character */
TOK_SPEC, /* a storage class specifier, qualifier, type, etc. */
TOK_COUNT
} tokenType;
/* This describes the scoping of the current statement.
*/
typedef enum eTagScope {
SCOPE_GLOBAL, /* no storage class specified */
SCOPE_STATIC, /* static storage class */
SCOPE_EXTERN, /* external storage class */
SCOPE_FRIEND, /* declares access only */
SCOPE_TYPEDEF, /* scoping depends upon context */
SCOPE_COUNT
} tagScope;
typedef enum eDeclaration {
DECL_NONE,
DECL_BASE, /* base type (default) */
DECL_CLASS,
DECL_ENUM,
DECL_FUNCTION,
DECL_IGNORE, /* non-taggable "declaration" */
DECL_INTERFACE,
DECL_NAMESPACE,
DECL_NOMANGLE, /* C++ name demangling block */
DECL_PACKAGE,
DECL_STRUCT,
DECL_UNION,
DECL_COUNT
} declType;
typedef enum eVisibilityType {
ACCESS_UNDEFINED,
ACCESS_PRIVATE,
ACCESS_PROTECTED,
ACCESS_PUBLIC,
ACCESS_COUNT
} accessType;
/* Information about the parent class of a member (if any).
*/
typedef struct sMemberInfo {
boolean isMember; /* is declared entity a member? */
boolean immediate; /* immediate class name preceding declaration?*/
accessType access; /* access of current statement */
accessType accessDefault; /* access default for current statement */
} memberInfo;
typedef struct sTokenInfo {
tokenType type;
keywordId keyword;
vString * name; /* the name of the token */
unsigned long lineNumber; /* line number of tag */
fpos_t filePosition; /* file position of line containing name */
} tokenInfo;
/* Describes the statement currently undergoing analysis.
*/
typedef struct sStatementInfo {
tagScope scope;
declType declaration; /* specifier associated with TOK_SPEC */
boolean gotName; /* was a name parsed yet? */
boolean haveQualifyingName; /* do we have a name we are considering? */
boolean gotParenName; /* was a name inside parentheses parsed yet? */
boolean gotArgs; /* was a list of parameters parsed yet? */
boolean isPointer; /* is 'name' a pointer? */
unsigned int tokenIndex; /* currently active token */
tokenInfo * token[(int)NumTokens];
tokenInfo * context; /* information on name of current context */
memberInfo member; /* information regarding parent class/struct */
struct sStatementInfo *parent; /* statement we are nested within */
} statementInfo;
/* Describes the type of tag being generated.
*/
typedef enum eTagType {
TAG_UNDEFINED,
TAG_CLASS, /* class name */
TAG_ENUM, /* enumeration name */
TAG_ENUMERATOR, /* enumerator (enumeration value) */
TAG_FIELD, /* field (Java) */
TAG_FUNCTION, /* function definition */
TAG_INTERFACE, /* interface declaration */
TAG_MEMBER, /* structure, class or interface member */
TAG_METHOD, /* method declaration */
TAG_NAMESPACE, /* namespace name */
TAG_PACKAGE, /* package name */
TAG_PROTOTYPE, /* function prototype or declaration */
TAG_STRUCT, /* structure name */
TAG_TYPEDEF, /* typedef name */
TAG_UNION, /* union name */
TAG_VARIABLE, /* variable definition */
TAG_EXTERN_VAR, /* external variable declaration */
TAG_COUNT /* must be last */
} tagType;
typedef struct sParenInfo {
boolean isPointer;
boolean isParamList;
boolean isKnrParamList;
boolean isNameCandidate;
boolean invalidContents;
boolean nestedArgs;
unsigned int parameterCount;
} parenInfo;
/*============================================================================
= Data definitions
============================================================================*/
static jmp_buf Exception;
static const keywordDesc KeywordTable[] = {
/* C++ */
/* ANSI C | Java */
/* keyword keyword ID \ | / */
{ "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 0 } },
{ "abstract", KEYWORD_ABSTRACT, { 0, 0, 1 } },
{ "boolean", KEYWORD_BOOLEAN, { 0, 0, 1 } },
{ "byte", KEYWORD_BYTE, { 0, 0, 1 } },
{ "catch", KEYWORD_CATCH, { 0, 1, 0 } },
{ "char", KEYWORD_CHAR, { 1, 1, 1 } },
{ "class", KEYWORD_CLASS, { 0, 1, 1 } },
{ "const", KEYWORD_CONST, { 1, 1, 1 } },
{ "double", KEYWORD_DOUBLE, { 1, 1, 1 } },
{ "enum", KEYWORD_ENUM, { 1, 1, 0 } },
{ "explicit", KEYWORD_EXPLICIT, { 0, 1, 0 } },
{ "exte